import { PropType, VNodeChild } from 'vue';

/**
 * PropType 链式构建器
 */
class PropTypeBuilder<T = any> {
  private propConfig: any = {};

  constructor(type?: any) {
    if (type !== undefined) {
      this.propConfig.type = type;
    }
  }

  /**
   * 设置默认值
   */
  def(defaultValue: T) {
    this.propConfig.default = defaultValue;
    return this.propConfig;
  }

  /**
   * 设置为必填
   */
  required() {
    this.propConfig.required = true;
    return this.propConfig;
  }

  /**
   * 设置为必填（别名）
   */
  get isRequired() {
    this.propConfig.required = true;
    return this.propConfig;
  }

  /**
   * 获取配置
   */
  get() {
    return this.propConfig;
  }
}

/**
 * Vue props 类型工具函数
 */
export const propTypes = {
  /**
   * 任意类型
   */
  any: new PropTypeBuilder<any>(),

  /**
   * 字符串类型
   */
  string: new PropTypeBuilder<string>(String),

  /**
   * 数字类型
   */
  number: new PropTypeBuilder<number>(Number),

  /**
   * 布尔类型
   */
  bool: new PropTypeBuilder<boolean>(Boolean),

  /**
   * 数组类型
   */
  array: new PropTypeBuilder<any[]>(Array),

  /**
   * 对象类型
   */
  object: new PropTypeBuilder<Record<string, any>>(Object),

  /**
   * 函数类型
   */
  func: new PropTypeBuilder<(...args: any[]) => any>(Function),

  /**
   * 日期类型
   */
  date: new PropTypeBuilder<Date>(Date),

  /**
   * VNode 类型
   */
  node: new PropTypeBuilder<VNodeChild>([String, Object, Function])
};

/**
 * 创建带默认值的 prop
 */
export function createProp<T>(type: any, defaultValue?: T) {
  return {
    type: type as PropType<T>,
    default: defaultValue
  };
}

/**
 * 创建必填的 prop
 */
export function createRequiredProp<T>(type: any) {
  return {
    type: type as PropType<T>,
    required: true as const
  };
}

export default propTypes;